package cn.iocoder.yudao.framework.business.interest.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.service.impl.AbstractService;
import cn.iocoder.yudao.framework.business.interest.dao.InterestMapper;
import cn.iocoder.yudao.framework.business.interest.pojo.po.InterestEntity;
import cn.iocoder.yudao.framework.business.interest.pojo.vo.AppInterestVO;
import cn.iocoder.yudao.framework.common.exception.KnownServiceException;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 喜好 Service 实现类，由子类继承，子类标注 @{@link org.springframework.stereotype.Service}
 * *
 * * @author 山野羡民
 */
//@org.springframework.stereotype.Service
public abstract class AppInterestBaseService<SNAPSHOT extends Serializable, DO extends InterestEntity, RESP extends AppInterestVO> extends AbstractService<DO, RESP> implements AppInterestService<SNAPSHOT> {

    @Override
    public Boolean toggle(Long bizId, Long userId) {
        SNAPSHOT snapshot = validateSnapshotExists(bizId);
        CoreMapper<DO> mapper = getInjectedMapper();
        if (mapper instanceof InterestMapper<DO> interestBaseMapper) {
            DO entity = interestBaseMapper.selectOneByBizIdAndUserId(bizId, userId, null);
            if (entity == null) {
                // 注意：需确保 DO 有无参构造函数，例如使用 @@NoArgsConstructor 注解
                entity = ReflectUtil.newInstance(resolveEntityClass());
                entity.setBizId(bizId);
                entity.setUserId(userId);
                entity.setSnapshot(JsonUtils.toJsonString(snapshot));
                entity.setRecycled(false);
                mapper.insert(entity);
                entity.setUserId(userId);
            } else {
                if (Boolean.TRUE.equals(entity.getRecycled())) {
                    entity.setSnapshot(JsonUtils.toJsonString(snapshot));
                    entity.setRecycled(false);
                } else {
                    entity.setRecycled(true);
                }
                mapper.updateById(entity);
            }
            return Boolean.TRUE.equals(entity.getRecycled()) ? null : true;
        }
        throw new KnownServiceException("Mapper 必须是" + InterestMapper.class.getSimpleName() + " 的子类");
    }

    @Override
    public boolean isTrue(Long bizId, Long userId) {
        if (bizId == null || bizId <= 0) {
            return false;
        }
        if (userId == null || userId <= 0) {
            return false;
        }
        CoreMapper<DO> mapper = getInjectedMapper();
        if (mapper instanceof InterestMapper<DO> interestBaseMapper) {
            DO result = interestBaseMapper.selectOneByBizIdAndUserId(bizId, userId, false);
            return result != null;
        }
        throw new KnownServiceException("Mapper 必须是" + InterestMapper.class.getSimpleName() + " 的子类");
    }

    @Override
    public Map<Long, Boolean> getStateMap(Set<Long> bizIds, Long userId) {
        if (CollUtil.isEmpty(bizIds)) {
            return new HashMap<>();
        }
        if (userId == null || userId <= 0) {
            return new HashMap<>();
        }
        CoreMapper<DO> mapper = getInjectedMapper();
        if (mapper instanceof InterestMapper<DO> interestBaseMapper) {
            List<DO> list = interestBaseMapper.selectListByBizIdsAndUserId(bizIds, userId);
            if (CollUtil.isEmpty(list)) {
                return new HashMap<>();
            }
            return CollectionUtils.convertMap(list, DO::getBizId, aDo -> !Boolean.TRUE.equals(aDo.getRecycled()));
        }
        throw new KnownServiceException("Mapper 必须是" + InterestMapper.class.getSimpleName() + " 的子类");
    }

    @Override
    public Integer getCount(Long userId) {
        if (userId == null || userId <= 0) {
            return 0;
        }
        CoreQueryWrapper<DO> wrapper = new CoreQueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.eq("recycled", false);
        Long aLong = getInjectedMapper().selectCount(wrapper);
        if (aLong == null) {
            return 0;
        }
        return Math.toIntExact(aLong);
    }

}
